﻿namespace Skymate
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;

    using Abp.Dependency;
    using Abp.Events.Bus;

    using Skymate.Commands;

    using WeifenLuo.WinFormsUI.Docking;

    public partial class ClientForm : DockContent, ITransientDependency
    {
        public ClientForm()
        {
            this.InitializeComponent();

            EventBus.Default.Register<QueryRequestOnlineEvent>(this.QueryRequestOnlineEventHandler);
            EventBus.Default.Register<LightGroupQueryResponseEvent>(this.LightGroupQueryResponseEvent);
            EventBus.Default.Register<ShowLogEvent>(this.ShowLogEventHandler);
            EventBus.Default.Register<PhaseQueryResponseEvent>(this.PhaseQueryResponseEventHandler);

            EventBus.Default.Register<DatetimeResponseEvent>(this.DatetimeResponseEventHandler);
            EventBus.Default.Register<LightColorStateReportedEvent>(this.LightColorStateReportedEventHandler);

            EventBus.Default.Register<TimingPlanQueryResponseEvent>(this.TimingPlanQueryResponseEventHandler);
            EventBus.Default.Register<SchedSolutionQueryResponseEvent>(this.SchedSolutionQueryResponseEventHandler);
        }

        public LightAppSession Session { get; set; }
        
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            EventBus.Default.Unregister<QueryRequestOnlineEvent>(this.QueryRequestOnlineEventHandler);
        }
        
        private void SchedSolutionQueryResponseEventHandler(SchedSolutionQueryResponseEvent data)
        {
            if (data.Ip != this.Session.RemoteEndPoint.ToString())
            {
                return;
            }

            this.Invoke(new Action(
                () =>
                {
                    this.lv_sched_solution.BeginUpdate();
                    foreach (var phase in data.SchedSolutions)
                    {
                        this.AddSchedSolution(phase);
                    }

                    this.lv_sched_solution.EndUpdate();
                }));
        }

        /// <summary>
        /// 信号配时方案
        /// </summary>
        /// <param name="data">
        /// The data.
        /// </param>
        private void TimingPlanQueryResponseEventHandler(TimingPlanQueryResponseEvent data)
        {
            if (data.Ip != this.Session.RemoteEndPoint.ToString())
            {
                return;
            }

            this.Invoke(new Action(
                () =>
                {
                    this.lv_timingplan.BeginUpdate();
                    foreach (var phase in data.TimingPlans)
                    {
                        this.AddTimingPlan(phase);
                    }

                    this.lv_timingplan.EndUpdate();
                }));
        }

        private ListViewItem AddSchedSolution(SchedSolution solution)
        {
            ListViewItem item = new ListViewItem();
            var values = solution.ToStrings();
            item.Text = values[0];
            for (int i = 1; i < values.Count(); i++)
            {
                item.SubItems.Add(values[i]);
            }

            item.Tag = solution;
            this.lv_sched_solution.Items.Add(item);
            return item;
        }

        private ListViewItem AddTimingPlan(TimingPlan phase)
        {
            ListViewItem item = new ListViewItem();
            var values = phase.ToStrings();
            foreach (string t in values)
            {
                item.SubItems.Add(t);
            }

            item.Tag = phase;
            this.lv_timingplan.Items.Add(item);
            return item;
        }
        
        private void LightColorStateReportedEventHandler(LightColorStateReportedEvent data)
        {
            if (data.Ip != this.Session.RemoteEndPoint.ToString())
            {
                return;
            }

            this.Invoke(new Action(
                () =>
                {
                    this.lv_lightColor.BeginUpdate();
                    var colors = data.LightColorState.LightColors.ToArray();
                    for (int i = 0; i < colors.Length; i++)
                    {
                        var color = colors[i];
                        ListViewItem item = new ListViewItem { Text = (i + 1).ToString() };
                        item.SubItems.Add(color.ToString());
                        this.lv_lightColor.Items.Add(item);
                    }

                    this.lv_lightColor.EndUpdate();
                }));
        }

        private void ClientForm_Load(object sender, EventArgs e)
        {
        }

        private void LightGroupQueryResponseEvent(LightGroupQueryResponseEvent data)
        {
            if (data.Ip != this.Session.RemoteEndPoint.ToString())
            {
                return;
            }

            this.Invoke(new Action(
                () =>
                {
                    this.lv_lightgroup.BeginUpdate();

                    foreach (var lightGroup in data.LightGroups)
                    {
                        ListViewItem item = new ListViewItem();
                        var values = lightGroup.ToStrings();
                        item.Text = values[0];
                        for (int i = 1; i < values.Length; i++)
                        {
                            item.SubItems.Add(values[i]);
                        }

                        item.Tag = lightGroup;
                        this.lv_lightgroup.Items.Add(item);
                    }
                    
                    this.lv_lightgroup.EndUpdate();
                }));
        }
        
        /// <summary>
        /// 联机查询命令处理
        /// </summary>
        /// <param name="data"></param>
        private void QueryRequestOnlineEventHandler(QueryRequestOnlineEvent data)
        {
            if (data.Ip != this.Session.RemoteEndPoint.ToString())
            {
                return;
            }

            this.Invoke(new Action(
                () =>
                {
                    this.ShowMessage("联机查询命令");
                }));
        }

        private void ShowLogEventHandler(ShowLogEvent data)
        {
            if (data.Ip != this.Session.RemoteEndPoint.ToString())
            {
                return;
            }

            this.Invoke(new Action(
                () =>
                {
                    this.ShowMessage(data.Message, data.Data);
                }));
        }

        private void PhaseQueryResponseEventHandler(PhaseQueryResponseEvent data)
        {
            if (data.Ip != this.Session.RemoteEndPoint.ToString())
            {
                return;
            }

            this.Invoke(new Action(
                () =>
                    {
                    this.lv_phase.BeginUpdate();
                    foreach (var phase in data.Phases)
                    {
                        ListViewItem item = new ListViewItem();
                        var values = phase.ToStrings();
                        item.Text = values[0];
                        for (int i = 1; i < values.Length; i++)
                        {
                            item.SubItems.Add(values[i]);
                        }

                        item.Tag = phase;
                        this.lv_phase.Items.Add(item);
                    }
                    
                    this.lv_phase.EndUpdate();
                }));
        }

        private void ShowMessage(string message, string dataMsg = "")
        {
            this.listView1.BeginUpdate();
            ListViewItem item = new ListViewItem { Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") };
            item.SubItems.Add(message);
            item.SubItems.Add(dataMsg);

            this.listView1.Items.Insert(0, item);
            this.listView1.EndUpdate();
        }

        private void bt_setNow_Click(object sender, EventArgs e)
        {
            this.Session.SetDate(DateTime.Now);
        }

        private void btn_yesday_Click(object sender, EventArgs e)
        {
            this.Session.SetDate(DateTime.Now.AddDays(-1));
        }

        private void btn_get_teleseme_date_Click(object sender, EventArgs e)
        {
            this.Session.RequestDatetime();
        }

        private void btn_query_light_group_Click(object sender, EventArgs e)
        {
            this.Session.RequestLightGroup();
        }
        
        private void btn_request_phase_Click(object sender, EventArgs e)
        {
            
            this.Session.RequestPhase();
        }

        private void DatetimeResponseEventHandler(DatetimeResponseEvent data)
        {
            if (data.Ip != this.Session.RemoteEndPoint.ToString())
            {
                return;
            }

            this.Invoke(new Action(
                () =>
                {
                    this.lb_xhj_date.Text = data.Date.ToString("yyyy-MM-dd HH:mm:ss");
                }));
        }

        private void lv_phase_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
        }

        /// <summary>
        /// 相位选中项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lv_phase_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            this.pg_phase.SelectedObject = e.Item.Tag as Phase;
        }

        private void lv_lightgroup_SelectedIndexChanged(object sender, EventArgs e)
        {
        }

        /// <summary>
        /// 灯组项选中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lv_lightgroup_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            this.pg_light_group.SelectedObject = e.Item.Tag as LightGroup;
        }

        private void btn_create_phase_Click(object sender, EventArgs e)
        {
            var phase = new Phase();

            ListViewItem item = new ListViewItem();
            var values = phase.ToStrings();
            item.Text = values[0];
            for (int i = 1; i < values.Length; i++)
            {
                item.SubItems.Add(values[i]);
            }
            item.Tag = phase;
            this.lv_phase.Items.Add(item);

            item.Selected = true;
        }

        private void btn_remove_phase_Click(object sender, EventArgs e)
        {
            if (this.lv_phase.SelectedItems.Count <= 0)
            {
                MessageBox.Show("没有选中行", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            var item = this.lv_phase.SelectedItems[0];
            item.Remove();
        }

        private void btn_remove_lightgroup_Click(object sender, EventArgs e)
        {
            if (this.lv_lightgroup.SelectedItems.Count <= 0)
            {
                MessageBox.Show("没有选中行", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var item = this.lv_lightgroup.SelectedItems[0];
            item.Remove();
        }

        private void btn_new_lightgroup_Click(object sender, EventArgs e)
        {
            var lightGroup = new LightGroup();

            var item = this.AddLightGroup(lightGroup);
            item.Selected = true;
        }

        private ListViewItem AddLightGroup(LightGroup lightGroup)
        {
            ListViewItem item = new ListViewItem();
            var values = lightGroup.ToStrings();
            item.Text = values[0];
            for (int i = 1; i < values.Length; i++)
            {
                item.SubItems.Add(values[i]);
            }

            item.Tag = lightGroup;
            this.lv_lightgroup.Items.Add(item);

            return item;
        }

        private void btn_save_phase_Click(object sender, EventArgs e)
        {
            var phases = this.lv_phase.Items.Cast<ListViewItem>().Select(c => c.Tag as Phase).ToList();
            this.Session.SetPhases(phases);
        }

        private void btn_save_light_group_Click(object sender, EventArgs e)
        {
            var groups = this.lv_lightgroup.Items.Cast<ListViewItem>().Select(c => c.Tag as LightGroup).ToList();
            
            this.Session.SetLightGroups(groups);
        }

        private void btn_request_light_color_Click(object sender, EventArgs e)
        {
            this.Session.RequestLightColor();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.Session.RequestTimingPlan();
        }

        private void btn_new_timingplan_Click(object sender, EventArgs e)
        {
            var obj = new TimingPlan();
            var item = this.AddTimingPlan(obj);
            item.Selected = true;
        }

        private void btn_remove_timingplan_Click(object sender, EventArgs e)
        {
            if (this.lv_timingplan.SelectedItems.Count <= 0)
            {
                MessageBox.Show("没有选中行", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var item = this.lv_timingplan.SelectedItems[0];
            item.Remove();
        }

        private void lv_timingplan_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            this.pg_timplan.SelectedObject = e.Item.Tag as TimingPlan;
        }

        private void pg_timplan_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            this.lv_timingplan.BeginUpdate();
            var selected = this.lv_timingplan.SelectedItems[0];

            var values = (this.pg_timplan.SelectedObject as TimingPlan).ToStrings();
            for (int i = 0; i < values.Length; i++)
            {
                selected.SubItems[i].Text = values[i];
            }

            this.lv_timingplan.EndUpdate();
        }

        private void btn_save_timplan_Click(object sender, EventArgs e)
        {
            IList<TimingPlan> plnas =
                this.lv_timingplan.Items.Cast<ListViewItem>().Select(c => c.Tag as TimingPlan).ToList();
            
            this.Session.SetTimplans(plnas);
        }

        private void btn_new_sched_solution_Click(object sender, EventArgs e)
        {
            var obj = new SchedSolution();

            var item = this.AddSchedSolution(obj);
            item.Selected = true;
        }

        private void btn_remove_sched_solution_Click(object sender, EventArgs e)
        {
            if (this.lv_sched_solution.SelectedItems.Count <= 0)
            {
                MessageBox.Show("没有选中行", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var item = this.lv_sched_solution.SelectedItems[0];
            item.Remove();
        }

        private void btn_save_sched_solution_Click(object sender, EventArgs e)
        {
            IList<SchedSolution> plnas =
                this.lv_sched_solution.Items.Cast<ListViewItem>().Select(c => c.Tag as SchedSolution).ToList();
            
            this.Session.SetSchedSolutions(plnas);
        }

        private void lv_sched_solution_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            this.pg_sched_solution.SelectedObject = e.Item.Tag as SchedSolution;
        }

        private void pg_sched_solution_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            this.lv_sched_solution.BeginUpdate();
            var selected = this.lv_sched_solution.SelectedItems[0];

            var values = (this.pg_sched_solution.SelectedObject as SchedSolution).ToStrings();

            selected.Text = values[0];
            for (int i = 1; i < values.Length; i++)
            {
                selected.SubItems[i].Text = values[i];
            }

            this.lv_sched_solution.EndUpdate();
        }

        private void btn_query_sched_solution_Click(object sender, EventArgs e)
        {
            this.Session.RequestSchedSolution();
        }

        /// <summary>
        /// 灯组属性值发生改变
        /// </summary>
        /// <param name="s"></param>
        /// <param name="e"></param>
        private void pg_light_group_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            var data = this.pg_light_group.SelectedObject as LightGroup;

            this.lv_lightgroup.BeginUpdate();
            var selected = this.lv_lightgroup.SelectedItems[0];

            var values = data.ToStrings();
            selected.Text = values[0];
            for (int i = 1; i < values.Length; i++)
            {
                selected.SubItems[i].Text = values[i];
            }

            lv_lightgroup.EndUpdate();
            
        }

        private void pg_phase_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            var data = this.pg_light_group.SelectedObject as Phase;

            this.lv_phase.BeginUpdate();
            var selected = this.lv_phase.SelectedItems[0];

            var values = data.ToStrings();
            for (int i = 0; i < values.Length; i++)
            {
                selected.SubItems[i].Text = values[i];
            }

            this.lv_phase.EndUpdate();
        }
    }
}
